<?php
defined('SYS_RUN') or exit();

class Session
{
    /**
     * DB connection object
     * @var object
     */
    private $db;

    public function __construct() {
        $this->db = Lib::get('database')->mongo()->session;

        session_set_save_handler(
            array($this, 'open'),
            array($this, 'close'),
            array($this, 'read'),
            array($this, 'write'),
            array($this, 'destroy'),
            array($this, 'gc')
        );
    }

    public function init() {
        session_start();
    }

    public function set($name, $value) {
        $_SESSION[$name] = serialize($value);
    }

    public function get($name) {
        if(isset($_SESSION[$name]))
            return unserialize($_SESSION[$name]);
        else return false;
    }

    public function open() {
        return true;
    }

    public function close() {
        return true;
    }

    public function read($sessionId) {
        $sessionData = $this->db->findOne(array(
            'sessionId' => $sessionId
        ));
        if(is_null($sessionData)) {
            $this->db->insert(array(
                'sessionId' => $sessionId,
                'data'      => '',
                'timestamp' => time()
            ));
            return "";
        }
        return unserialize($sessionData['data']);
    }

    public function write($sessionId, $data) {
        $sessionData = $this->db->findOne(array(
            'sessionId' => $sessionId
        ));
        $sessionData['data'] = serialize($data);
        $this->db->save($sessionData);
        return true;
    }

    public function destroy($sessionId) {
        $this->db->remove(array(
            'sessionId' => $sessionId
        ));
        return true;
    }

    public function gc($maxLifeTime) {
        $currentTime = time();
        $this->db->remove(array(
            'timestamp' => array(
                    '$gt'   => $maxLifeTime + $currentTime
            )
        ));
        return true;
    }
}